﻿using UnityEngine;
using System.Collections;

namespace DoomWad
{
	public class WadDefs
	{
		public const int PIXELS_PER_UNIT = 64;
		public const int PIXELS_PER_FLAT = 64;
	}

	public class wadinfo_t
	{
		public string identification;
		public int numlumps;
		public int infotableofs;
	}

	public struct filelump_t
	{
		public int filepos;
		public int size;
		public string name;
	}

	public enum SideType
	{
		TOP,
		MIDDLE,
		BOTTOM,
		MAX,
	}

	public enum FlatType
	{
		FLOOR,
		CEILING,
		MAX,
	}

	//
	// Map level types.
	// The following data structures define the persistent format
	// used in the lumps of the WAD files.
	//

	// Lump order in a map WAD: each map needs a couple of lumps
	// to provide a complete scene geometry description.
	public enum MapLumpType
	{
		ML_LABEL,		// A separator, name, ExMx or MAPxx
		ML_THINGS,		// Monsters, items..
		ML_LINEDEFS,		// LineDefs, from editing
		ML_SIDEDEFS,		// SideDefs, from editing
		ML_VERTEXES,		// Vertices, edited and BSP splits generated
		ML_SEGS,		// LineSegs, from LineDefs split by BSP
		ML_SSECTORS,		// SubSectors, list of LineSegs
		ML_NODES,		// BSP nodes
		ML_SECTORS,		// Sectors, from editing
		ML_REJECT,		// LUT, sector-sector visibility	
		ML_BLOCKMAP		// LUT, motion clipping, walls/grid element
	}

	public enum LineDefFlags
	{
		// Solid, is an obstacle.
		ML_BLOCKING = 1,

		// Blocks monsters only.
		ML_BLOCKMONSTERS = 2,

		// Backside will not be present at all
		//  if not two sided.
		ML_TWOSIDED = 4,

		// If a texture is pegged, the texture will have
		// the end exposed to air held constant at the
		// top or bottom of the texture (stairs or pulled
		// down things) and will move with a height change
		// of one of the neighbor sectors.
		// Unpegged textures allways have the first row of
		// the texture at the top pixel of the line for both
		// top and bottom textures (use next to windows).

		// upper texture unpegged
		ML_DONTPEGTOP = 8,

		// lower texture unpegged
		ML_DONTPEGBOTTOM = 16,

		// In AutoMap: don't map as two sided: IT'S A SECRET!
		ML_SECRET = 32,

		// Sound rendering: don't let sound cross two of these.
		ML_SOUNDBLOCK = 64,

		// Don't draw on the automap at all.
		ML_DONTDRAW = 128,

		// Set if already seen, thus drawn in automap.
		ML_MAPPED = 256
	}

	public enum NodeFlags
	{
		Leaf = 0x8000
	}

	// A single Vertex.
	public struct mapvertex_t
	{
		public short x;
		public short y;

		public mapvertex_t( int x, int y )
		{
			this.x = ( short ) x;
			this.y = ( short ) y;
		}

		public static explicit operator Vector2( mapvertex_t v )
		{
			return new Vector2( v.x, v.y );
		}

		public static mapvertex_t operator +( mapvertex_t a, mapvertex_t b )
		{
			return new mapvertex_t( a.x + b.x, a.y + b.y );
		}

		public static mapvertex_t operator -( mapvertex_t a, mapvertex_t b )
		{
			return new mapvertex_t( a.x - b.x, a.y - b.y );
		}
	}

	// A SideDef, defining the visual appearance of a wall,
	// by setting textures and offsets.
	public struct mapsidedef_t
	{
		public short textureoffset; // x offset
		public short rowoffset; // y offset
		public string toptexture;
		public string bottomtexture;
		public string midtexture;
		// Front sector, towards viewer.
		public short sector;
	}

	// A LineDef, as used for editing, and as input
	// to the BSP builder.
	public struct maplinedef_t
	{
		public short v1;
		public short v2;
		public short flags;
		public short special;
		public short tag;
		// lsidenum will be -1 if one sided
		public short rsidenum;
		public short lsidenum;
	}

	// Sector definition, from editing.
	public struct mapsector_t
	{
		public short floorheight;
		public short ceilingheight;
		public string floorpic;
		public string ceilingpic;
		public short lightlevel;
		public short special;
		public short tag;
	}

	// SubSector, as generated by BSP.
	public struct mapsubsector_t
	{
		public short numsegs;
		// Index of first one, segs are stored sequentially.
		public short firstseg;	
	}


	// LineSeg, generated by splitting LineDefs
	// using partition lines selected by BSP builder.
	public struct mapseg_t
	{
		public short v1;
		public short v2;
		public short angle;
		public short linedef;
		public short side;
		public short offset;
	}

	public struct mapnode_t
	{
		public short x;
		public short y;
		public short dx;
		public short dy;
		public Rect rbox;
		public Rect lbox;
		public short rchild;
		public short lchild;

		public bool lIsLeaf { get { return lchild < 0; } }
		public bool rIsLeaf { get { return rchild < 0; } }
	}

	public struct mappatch_t
	{
		public short originx;
		public short originy;
		public short patch;
		public short stepdir;
		public short colormap;
	}

	public class maptexture_t
	{
		public string name;
		public bool masked;
		public short width;
		public short height;
		public int columndirectory;	// OBSOLETE
		public short patchcount;
		public mappatch_t[] patches;
	}

	public class patch_t
	{
		public short width; // bounding box size
		public short height;
		public short leftoffset; // pixels to the left of origin 
		public short topoffset;	// pixels below the origin 
		public int[] columnofs;	// only [width] used
		public byte[] pixels; // 2 bytes per pixel ([0]- color index, [1]- alpha flag (0-invisible, 1-visible))
	}
}
